package es.usal.proyecto.View;


import java.io.ByteArrayOutputStream;

import es.usal.proyecto.R;
import com.googlecode.leptonica.android.Pix;
import com.googlecode.leptonica.android.ReadFile;
import com.googlecode.tesseract.android.TessBaseAPI;

import es.usal.proyecto.Controller.LanguagesController;
import es.usal.proyecto.Controller.Interfaces.IAsyncResponse;
import es.usal.proyecto.Controller.Interfaces.IDrawResponse;
import es.usal.proyecto.Controller.Tasks.TranslateTask;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.widget.FrameLayout;
import android.widget.Toast;
import android.util.Log;
import android.view.*;

public class CameraActivity extends Activity implements IAsyncResponse, IDrawResponse{

    private Camera mCamera;
    private CameraPreview mPreview;
    private OverlayView overlayer;
    private Bitmap bitmapPicture;
    private Bitmap bitmap;
    private Integer userLang;
    private Integer outLang;
    private LanguagesController langCtrler;
     
    
    private Camera.PictureCallback mPicture = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

        	mCamera.startPreview();
        	
        	bitmapPicture = null;
        	BitmapFactory.Options options=new BitmapFactory.Options();
            options.inSampleSize = 5;
        	bitmapPicture = BitmapFactory.decodeByteArray(data, 0, data.length);
        	bitmap = bitmapPicture.copy(Bitmap.Config.ARGB_8888, true);

        	getOCR();
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
    	
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        
        getActionBar().setDisplayHomeAsUpEnabled(true);
        
        if (savedInstanceState == null) {
            Bundle extras = getIntent().getExtras();
            if(extras == null) {
                userLang = null;
                outLang = null;
            } else {
                userLang = extras.getInt("USERLANG");
                outLang = extras.getInt("OUTLANG");
            }
        } else {
            userLang = (Integer) savedInstanceState.getSerializable("USERLANG");
            outLang = (Integer) savedInstanceState.getSerializable("OUTLANG");
        }
    }
    
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater mnuInflater = getMenuInflater();
	    mnuInflater.inflate(R.menu.camactionbar, menu);     
	    
	    return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {

	    case android.R.id.home:
	        NavUtils.navigateUpFromSameTask(this);
	        return true;
	        
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}
    
    @Override
    public void onResume(){
    	super.onResume();
	    if (Build.VERSION.SDK_INT >=
		    Build.VERSION_CODES.GINGERBREAD){
		    mCamera = Camera.open(0);
	    }
	    else
	    {
	    	mCamera = Camera.open();
	    }
        // Create our Preview view and set it as the content of our activity. 
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
        
        overlayer = new OverlayView(getBaseContext());
        overlayer.delegate = this;
        preview.addView(overlayer);
        
        Toast.makeText(this, R.string.MakeAreaGuide, Toast.LENGTH_LONG).show();
    }
    
    @Override
    public void onPause(){
	    super.onPause();
	    if (mCamera != null){
		    mCamera.release();
		    mCamera = null;
	    }
    }
    
    private void getOCR(){

    	TessBaseAPI baseApi = new TessBaseAPI();

    	langCtrler = new LanguagesController(getBaseContext());
    	String outLangCode = langCtrler.getLangOCRCode(outLang);
    	String langPath = langCtrler.getLangPath();
    	
        baseApi.init(langPath, outLangCode);
        Bitmap subPhoto = getSubPhoto();
        
        Log.e("Commpressed   dimensions", subPhoto.getWidth()+" "+subPhoto.getHeight());
        Log.e("Original   dimensions", bitmap.getWidth()+" "+bitmap.getHeight());
        
        Pix px = ReadFile.readBitmap(subPhoto);
        
        baseApi.setImage(px);
        // this call below will return the recognized text
        String text =  baseApi.getUTF8Text();
		
        Toast.makeText(this, text, Toast.LENGTH_LONG).show();
        
        if(text.trim().isEmpty() || text.length() > 200){
        	Toast.makeText(this, R.string.BadRecognition, Toast.LENGTH_LONG).show();
        }else{
	        try {
	        	TranslateTask task = new TranslateTask();
	        	String[] params = new String[2];
	        	params[0] = userLang.toString();
	        	params[1] = text;
	        	task.delegate = this;
	        	task.execute(params);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
	}

	@Override
	public void processFinish(String output) {
		// TODO Auto-generated method stub
		Toast.makeText(this, output, Toast.LENGTH_LONG).show();
	}

	@Override
	public void rectAreaCreated() {
		// TODO Auto-generated method stub
		mCamera.takePicture(null, null, mPicture);
	}

	private int[] setRectangleCoordinates(){
		
		
	    double heightRatio = (double)bitmap.getHeight()/(double)overlayer.getViewHeight();
	    double widthRatio = (double)bitmap.getWidth()/(double)overlayer.getViewWidth();

	    int x0 = (int) (widthRatio*(double)overlayer.getX0());
 
        int y0 = (int) (heightRatio*(double)overlayer.getY0());

        int x1 = (int)(widthRatio*(double)overlayer.getX1());

        int y1 = (int)(heightRatio*(double)overlayer.getY1());

        return new int[]{x0,y0,x1,y1};
	}
	
	private Bitmap getSubPhoto(){
		
		int[] rectCoords = setRectangleCoordinates();
		
		int width = rectCoords[2]-rectCoords[0];
		int height = rectCoords[3]-rectCoords[1];
		
        int[] pixelRect = new int[height*width];
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap.getPixels(pixelRect, 0, width, rectCoords[0], rectCoords[1], width, height);
        bitmap = Bitmap.createBitmap(pixelRect, 0, width, width, height, Config.ARGB_8888);
        bitmap.compress(CompressFormat.JPEG, 100, bos);
        byte[] square = bos.toByteArray();
        bitmap = BitmapFactory.decodeByteArray(square, 0, bos.size());
        
        Bitmap decoded = null;
        
        if(bitmap.getHeight() > 400 || bitmap.getWidth() > 400){
        	decoded = Bitmap.createScaledBitmap(bitmap,400, 400, true);
        }else{
        	decoded = bitmap;
        }
        
        return decoded;
	}
    
}
